<script lang="ts" setup>
import {ref, computed, onMounted, watch} from 'vue';
import {Document, Delete, CopyDocument} from '@element-plus/icons-vue';
import {Codemirror} from 'vue-codemirror';
import {EditorState} from '@codemirror/state';
import {EditorView, keymap} from '@codemirror/view';
import {json} from '@codemirror/lang-json';
import {basicSetup} from 'codemirror';

// JSON输入和输出内容
const inputJson = ref('');
const outputJson = ref('');
const isFormatting = ref(false);
const errorMessage = ref('');
const successMessage = ref('');

// 编辑器扩展配置
const editorExtensions = [
  basicSetup,
  json(),
  EditorView.lineWrapping,
  EditorView.updateListener.of(update => {
    if (update.docChanged) {
      const newText = update.state.doc.toString();
      inputJson.value = newText;
      handleInputChange();
    }
  })
];

// 输出编辑器扩展配置
const outputEditorExtensions = [
  basicSetup,
  json(),
  EditorView.lineWrapping,
  EditorState.readOnly.of(true)
];

// 格式化JSON
const formatJson = () => {
  try {
    errorMessage.value = '';
    successMessage.value = '';
    isFormatting.value = true;

    if (!inputJson.value.trim()) {
      outputJson.value = '';
      return;
    }

    // 解析JSON并重新格式化
    const parsedJson = JSON.parse(inputJson.value);
    outputJson.value = JSON.stringify(parsedJson, null, 2);

    successMessage.value = 'JSON美化成功！';
    setTimeout(() => {
      successMessage.value = '';
    }, 2000);
  } catch (error: any) {
    errorMessage.value = `JSON解析错误: ${error.message}`;
    outputJson.value = '';
  } finally {
    isFormatting.value = false;
  }
};

// 压缩JSON
const compressJson = () => {
  try {
    errorMessage.value = '';
    successMessage.value = '';
    isFormatting.value = true;

    if (!inputJson.value.trim()) {
      outputJson.value = '';
      return;
    }

    // 解析JSON并压缩
    const parsedJson = JSON.parse(inputJson.value);
    outputJson.value = JSON.stringify(parsedJson);

    successMessage.value = 'JSON压缩成功！';
    setTimeout(() => {
      successMessage.value = '';
    }, 2000);
  } catch (error: any) {
    errorMessage.value = `JSON解析错误: ${error.message}`;
    outputJson.value = '';
  } finally {
    isFormatting.value = false;
  }
};

// 清空输入
const clearInput = () => {
  inputJson.value = '';
  outputJson.value = '';
  errorMessage.value = '';
  successMessage.value = '';
};

// 复制到剪贴板
const copyToClipboard = async (text: string) => {
  try {
    await navigator.clipboard.writeText(text);
    successMessage.value = '已复制到剪贴板！';
    setTimeout(() => {
      successMessage.value = '';
    }, 2000);
  } catch (error) {
    errorMessage.value = '复制失败，请手动复制';
  }
};

// 监听输入变化，自动格式化
const handleInputChange = () => {
  formatJson();
};
</script>

<template>
  <div class="json-beautify-container">
    <header class="json-beautify-header">
      <div class="header-actions">
        <el-button :loading="isFormatting" type="primary" @click="formatJson">
          <Document/>
          美化JSON
        </el-button>
        <el-button :loading="isFormatting" @click="compressJson">
          <Delete/>
          压缩JSON
        </el-button>
        <el-button @click="clearInput">
          <Delete/>
          清空
        </el-button>
      </div>
    </header>

    <div class="json-beautify-main">
      <!-- 左侧输入区域 -->
      <div class="editor-section">
        <div class="section-header">
          <h3>输入</h3>
          <el-button size="small" type="text" @click="copyToClipboard(inputJson)">
            <CopyDocument/>
            复制
          </el-button>
        </div>
        <div class="editor-container">
          <Codemirror
              v-model="inputJson"
              :autofocus="true"
              :extensions="editorExtensions"
              :indent-with-tab="true"
              :tab-size="2"
              class="json-editor"
              placeholder="请输入或粘贴JSON字符串"
          />
        </div>
      </div>

      <!-- 右侧输出区域 -->
      <div class="editor-section">
        <div class="section-header">
          <h3>输出</h3>
          <el-button size="small" type="text" @click="copyToClipboard(outputJson)">
            <CopyDocument/>
            复制
          </el-button>
        </div>
        <div class="editor-container">
          <Codemirror
              v-model="outputJson"
              :autofocus="false"
              :extensions="outputEditorExtensions"
              :indent-with-tab="true"
              :tab-size="2"
              class="json-editor"
              placeholder="美化后的JSON将显示在这里"
          />
        </div>
      </div>
    </div>

    <!-- 错误提示 -->
    <div class="json-beautify-footer">
      <el-alert
          v-if="errorMessage"
          :closable="false"
          :title="errorMessage"
          show-icon
          type="error"
      />
      <el-alert
          v-if="successMessage"
          :closable="false"
          :title="successMessage"
          show-icon
          type="success"
      />
    </div>
  </div>
</template>

<style lang="scss" scoped>
.json-beautify-container {
  width: 100%;
  height: 100%;
  padding: 20px;
  background-color: #f5f7fa;
  border-radius: 8px;
  box-sizing: border-box;

  .header-section {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 20px;

    .page-title {
      margin: 0;
      color: #303133;
      font-size: 20px;
      font-weight: 600;
    }

    .action-buttons {
      display: flex;
      gap: 10px;
    }
  }

  .message-section {
    margin-bottom: 20px;

    :deep(.el-alert) {
      margin-bottom: 10px;
    }
  }

  .json-beautify-main {
    display: flex;
    gap: 20px;
    height: calc(100% - 120px);

    .editor-section {
      flex: 1;
      background: #fff;
      border-radius: 8px;
      box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
      display: flex;
      flex-direction: column;
      overflow: hidden;

      .section-header {
        display: flex;
        justify-content: space-between;
        align-items: center;
        padding: 12px 20px;
        background: #fafafa;
        border-bottom: 1px solid #ebeef5;

        h3 {
          margin: 0;
          color: #606266;
          font-size: 16px;
          font-weight: 500;
        }
      }

      .editor-container {
        flex: 1;
        padding: 20px;
        box-sizing: border-box;
        overflow: hidden;

        .json-editor {
          width: 100%;
          height: 100%;
          border: 1px solid #dcdfe6;
          border-radius: 4px;
          overflow: hidden;

          &:focus-within {
            border-color: #409eff;
            box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
          }

          // 修复滚动问题：确保Codemirror编辑器能正常滚动
          :deep(.cm-editor) {
            height: 100% !important;
            overflow: hidden;
          }

          :deep(.cm-scroller) {
            overflow: auto !important;
            height: 100% !important;
          }

          // 美化滚动条
          :deep(.cm-scroller::-webkit-scrollbar) {
            width: 8px;
            height: 8px;
          }

          :deep(.cm-scroller::-webkit-scrollbar-track) {
            background: #f1f1f1;
            border-radius: 4px;
          }

          :deep(.cm-scroller::-webkit-scrollbar-thumb) {
            background: #c1c1c1;
            border-radius: 4px;

            &:hover {
              background: #a8a8a8;
            }
          }

          // 确保编辑器内容区域高度正确
          :deep(.cm-content) {
            min-height: 100%;
          }
        }
      }
    }
  }
}
</style>